package com.yanqu.road.server.cmd.base;

import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.PlayerModule;
import com.yanqu.road.server.gameplayer.module.season.SeasonRewardModule;
import com.yanqu.road.server.gameplayer.module.manor.ManorModule;
import com.yanqu.road.server.gameplayer.module.player.AttributeModule;
import com.yanqu.road.server.gameplayer.module.player.BeautyModule;
import com.yanqu.road.server.gameplayer.module.player.EarnSpeedModule;
import com.yanqu.road.server.gameplayer.module.task.TaskModule;
import com.yanqu.road.server.gameplayer.module.vehicle.VehicleBoneModule;
import com.yanqu.road.server.gameplayer.module.vehicle.VehicleModule;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.command.Command;
import com.yanqu.road.utils.config.Config;
import io.netty.channel.ChannelHandlerContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public abstract class AbstractCommand implements Command {

    protected static Logger log = LogManager.getLogger(AbstractCommand.class.getName());

    private static Logger cmdLogger = LogManager.getLogger("COMMAND_TIME");
    /**
     * 执行状态返回值
     */
    protected int ret = 0;

    public abstract boolean parseData(YanQuMessage packet) throws Exception;

    public abstract void execute(GamePlayer player, YanQuMessage packet) throws Exception;

    public abstract void sendData(GamePlayer player);

    public void execute(ChannelHandlerContext ctx, YanQuMessage packet) throws Exception {
        long userId = packet.getPlayerId();
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        try {
            if (parseData(packet)) {
                //调式模式下，输出日志；
                if (Config.isDebug()) {
                    log.debug("-------------收到消息--------{}: {} ", userId, packet.getCode());
                    if (isDebug()) {
                        String request = getRequestData();
                        cmdLogger.debug("----execute----player: {}, request: {}", player.getUserId(), request);
                    }
                }

                startChange(player);
                if (null != player) {
                    player.getModule(EarnSpeedModule.class).resetDay();
                    player.setLastPingTime(System.currentTimeMillis());
                }
                execute(player, packet);
                sendData(player);
            }
        } catch (Exception e) {
            if(null == player){
                log.info("execute cmd error, userId: {},code: {}", userId, packet.getCode(), e);
            }else {
                log.error("execute cmd error, userId: {},code: {}", userId, packet.getCode(), e);
            }
        } finally {
            finishChanges(player);
            if(player != null){
                try {
                    player.getCommandStatistics().addCommandData(packet.getCode(), 0);
                }catch (Exception e){
                    log.error("", e);
                }
            }
        }
    }

    private void startChange(GamePlayer player) {
        if (null != player) {
            player.getModule(TaskModule.class).startChanges();
            player.getModule(ActivityModule.class).startChanges();
        }
    }

    private void finishChanges(GamePlayer player) {
        if (null != player) {
            player.getModule(TaskModule.class).finishChanges();
            player.getModule(ActivityModule.class).finishChanges();
            player.getModule(AttributeModule.class).syncDataChange();
            player.getModule(BeautyModule.class).commitBeautyChange();
            player.getModule(PatronsModule.class).commitPatronsChange();
            player.getModule(ManorModule.class).getManorFishPondModel().commitFishAdd();
            player.getModule(SeasonRewardModule.class).syncChangeData();
            player.getModule(VehicleBoneModule.class).finishChanges();
            player.getModule(VehicleModule.class).finishChanges();
        }
    }
}
